﻿using System.Collections.Generic;
using System.Linq;
using LCA.Community.DAL.Interfaces;
using LCA.Community.DAL.Model;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using LCA.Community.DAL.Test.ModelFactories;
using LCA.Community.DAL;
using System;

namespace LCA.Community.DAL.Test
{
    /// <summary>
    ///This is a test class for GroupsRepositoryTest and is intended
    ///to contain all GroupsRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class GroupsRepositoryTest : BaseTestClass
    {
        private UsersFactory _usersFactory = new UsersFactory();
        private GroupsFactory _groupsFactory = new GroupsFactory();
        private GroupMembershipFactory _groupMembershipFactory = new GroupMembershipFactory();
        private List<User> _users;
        private List<Group> _groups;

        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize()]
        public void InitializeTest()
        {
            UnityContainerInitializer();

            var groupsRepository = _unityContainer.Resolve<IGroupsRepository>();
            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            var gMembershipsRepository = _unityContainer.Resolve<IGroupMembershipsRepository>();

            _users = _usersFactory.CreateList(5);
            _groups = _groupsFactory.CreateList(5,_users[0].RowKey);

            _users.ForEach(user => usersRepository.Add(user));
            _groups.ForEach(g => groupsRepository.Add(g));

            GroupMembership groupMembership;
            groupMembership = _groupMembershipFactory.CreateEntity(_users[1].RowKey, _groups[0].RowKey);
            gMembershipsRepository.Add(groupMembership);

            groupMembership = _groupMembershipFactory.CreateEntity(_users[2].RowKey, _groups[0].RowKey);
            gMembershipsRepository.Add(groupMembership);

            groupMembership = _groupMembershipFactory.CreateEntity(_users[2].RowKey, _groups[1].RowKey);
            gMembershipsRepository.Add(groupMembership);
        }

        /// <summary>
        /// Cleans up the test.
        /// </summary>
        [TestCleanup()]
        public void CleanupTest()
        {
            var groupsRepository = _unityContainer.Resolve<IGroupsRepository>();
            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            var gMembershipsRepository = _unityContainer.Resolve<IGroupMembershipsRepository>();

            groupsRepository.DeleteTestEntities();
            usersRepository.DeleteTestEntities();
            gMembershipsRepository.DeleteTestEntities();
        }

        /// <summary>
        ///A test for GetGroupMembers
        ///</summary>
        [TestMethod()]
        public void GetGroupMembersTest()
        {
            var target = _unityContainer.Resolve<IGroupsRepository>();
            string groupID = _groups[0].RowKey;
            List<User> expected = new List<User> { _users[0], _users[1], _users[2] };

            List<User> actual;
            actual = target.GetGroupMembers(groupID);

            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        ///A test for GetGroupsByUser
        ///</summary>
        [TestMethod()]
        public void GetGroupsByUserTest()
        {
            var target = _unityContainer.Resolve<IGroupsRepository>();
            string userID = _users[2].RowKey;
            List<Group> expected = new List<Group> { _groups[0], _groups[1] };

            List<Group> actual;
            actual = target.GetGroupsByUser(userID);

            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        ///A test for RecentGroups
        ///</summary>
        [TestMethod()]
        public void RecentGroupsTest()
        {
            var target = _unityContainer.Resolve<GroupsRepository>();
            var expected = _groupsFactory.CreateList(10, _users[1].RowKey);
            expected.ForEach(group => target.Add(group));
            expected.OrderBy(group => group.Timestamp);

            List<Group> actual;
            actual = target.RecentGroups;
            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        ///A test for GetGroupsContainingName
        ///</summary>
        [TestMethod()]
        public void GetGroupsContainingNameTest()
        {
            var target = _unityContainer.Resolve<GroupsRepository>();
            var name = "Group";
            var expected = _groups.Where(g => g.Name.Contains(name)).ToList();

            var actual = target.GetGroupsContainingName(name);
            CollectionAssert.AreEquivalent(expected, actual);
        }
    }
}
